package cn.gson.querydsl.dao.impl;

import cn.gson.querydsl.dao.Query;
import cn.gson.querydsl.dao.QueryHandler;
import jakarta.persistence.TransactionRequiredException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.query.MutationQuery;

import java.lang.reflect.Method;

/**
 * <p>****************************************************************************</p>
 * <ul style="margin:15px;">
 * <li>Description : ModifyingQueryHandler</li>
 * <li>Version     : 1.0</li>
 * <li>Creation    : 2024年07月19日</li>
 * <li>@author     : ____′↘夏悸</li>
 * </ul>
 * <p>****************************************************************************</p>
 */
public class ModifyingQueryHandler implements QueryHandler {
    private final SessionFactory sessionFactory;
    private final Query query;
    private final boolean isNative;
    private final Class<?> returnType;

    public ModifyingQueryHandler(SessionFactory sessionFactory, Query query, boolean isNative, Class<?> returnType) {
        this.sessionFactory = sessionFactory;
        this.query = query;
        this.isNative = isNative;
        this.returnType = returnType;
    }

    @Override
    public Object doQuery(Method method, Object[] args) throws Throwable {
        int executeUpdate = 0;
        try {
            executeUpdate = getQuery(query, args).executeUpdate();
        } catch (TransactionRequiredException tr) {
            throw new TransactionRequiredException("update/delete 还未开启事务：" + tr.getMessage());
        }
        if (returnType == void.class)
            return null;
        else if (returnType == long.class || returnType == Long.class)
            return (long) executeUpdate;
        else
            return executeUpdate;
    }

    private MutationQuery getQuery(Query query, Object[] args) {
        Session session = sessionFactory.openSession();
        MutationQuery exeQuery = null;
        if (isNative)
            exeQuery = session.createNativeMutationQuery(query.value());
        else
            exeQuery = session.createMutationQuery(query.value());
        if (args != null)
            for (int i = 0; i < args.length; i++)
                exeQuery.setParameter(i + 1, args[i]);
        return exeQuery;
    }
}
